package com.msi.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.io.File;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.Map;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import com.msi.Graph;
import com.msi.visualization.GraphVisualization;
import com.msi.visualization.MsiColor;
import com.msi.visualization.MsiColorLImpl;
import com.msi.test.*;

public class MenuAdapter {

	protected static final Logger log = Logger.getLogger(MenuAdapter.class);

	JMenuBar menuBar = new JMenuBar();
	JMenu fileMenu, submenu, toolsMenu, helpMenu;
	JMenuItem menuItem;
	JRadioButtonMenuItem rbMenuItem;
	JCheckBoxMenuItem cbMenuItem;
	JPanel parent;
	Settings settings = Settings.getInstance();

	private JFrame parentFrame;

	public MenuAdapter() {
		boolean rootIsConfigured = Logger.getRootLogger().getAllAppenders()
				.hasMoreElements();
		if (!rootIsConfigured)
			BasicConfigurator.configure();
	}

	JMenuBar createMenuBar(JPanel container) {
		parent = container;

		// Build the first menu.
		initializeMenuBar();

		String name = "Open";
		JMenuItem menuItem = createMenuItem(createListenerForOpen(), name);
		fileMenu.add(menuItem);

		String name3 = "Save";
		JMenuItem menuItem3 = createMenuItem(createListenerForSave(), name3);
		fileMenu.add(menuItem3);

		String name2 = "Generate";
		JMenuItem menuItem2 = createMenuItem(createListenerForGenerate(), name2);
		fileMenu.add(menuItem2);

		String colorName = "Compute";
		JMenuItem menuItemColor = createMenuItem(createListenerForCompute(),
				colorName);
		toolsMenu.add(menuItemColor);

		String testName = "Test";
		JMenuItem menuItemTest = createMenuItem(createListenerForTest(),
				testName);
		toolsMenu.add(menuItemTest);

		String autoLayoutName = "AutoLayout";
		JMenuItem menuItemAutoLayout = createMenuItem(
				createListenerForAutoLayout(), autoLayoutName);
		toolsMenu.add(menuItemAutoLayout);

		String infoName = "Info";
		JMenuItem menuItemInfo = createMenuItem(createListenerForInfo(),
				infoName);
		helpMenu.add(menuItemInfo);

		return menuBar;

	}

	private ActionListener createListenerForAutoLayout() {
		return new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				GraphVisualization.getInstance().useAutoLayout();
			}
		};
	}

	private ActionListener createListenerForInfo() {
		return new ActionListener() {

			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				JOptionPane.showMessageDialog(parentFrame,
						"\"Implementacja algorytmu CSP\"\n\n" + "Authors:\n"
								+ "Michał Kołodziejski\n" + "Karol Gałązka\n");
			}
		};
	}

	private ActionListener createListenerForTest() {
		return new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				TestWindow tw = new TestWindow(parentFrame, true);
				tw.setVisible(true);
			}
		};
	}

	private ActionListener createListenerForCompute() {
		return new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (GraphVisualization.getInstance().getGraph() == null)
					return;

				MsiColor gc = new MsiColorLImpl();
				gc.setGraph(GraphVisualization.getInstance().getGraph());
				;
				gc.color();
				GraphVisualization.getInstance().updateColors(gc);
				GraphVisualization.getInstance().repaint();

				showDialogWithResults(gc.getNumberOfColors(),
						gc.getComputationTime());
			}
		};
	}

	private ActionListener createListenerForSave() {
		return new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser fileChooser = new JFileChooser();
				int returnVal = fileChooser.showSaveDialog(fileChooser);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					writeGraphToFile(GraphVisualization.getInstance()
							.getGraph(), fileChooser.getSelectedFile());
				} else {
					log.info("Nie wybrano zadnego pliku");
				}
				log.info("Zapisywanie pliku zakończone");
			}
		};
	}

	private void initializeMenuBar() {
		fileMenu = new JMenu("File");

		toolsMenu = new JMenu("Tools");
		helpMenu = new JMenu("Help");

		menuBar.add(fileMenu);
		menuBar.add(toolsMenu);
		menuBar.add(helpMenu);
	}

	private ActionListener createListenerForGenerate() {
		ActionListener acL = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				GenerateWindow sw = new GenerateWindow();
				sw.setVisible(true);
			}
		};

		return acL;
	};

	private ActionListener createListenerForOpen() {
		ActionListener acL = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				log.info("Rozpoczynamy wczytywanie grafu z pliku");
				JFileChooser fileChooser = createFileChooser();
				int returnVal = fileChooser.showOpenDialog(parent);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					log.info("You chose to open this file: "
							+ fileChooser.getSelectedFile());
					Graph g = Graph
							.createGraphByNeighbourMatrix(FileWorker
									.extractNeighbourList(fileChooser
											.getSelectedFile()));
					Map<Integer, Point2D> map = FileWorker
							.extractCoordinatesFromFile(fileChooser
									.getSelectedFile());
					g.setCoordinates(map);
					GraphVisualization.getInstance().buildGraph(g);
				} else {
					log.info("Nie wybrano zadnego pliku");
				}
				log.info("Wczytywanie grafu z pliku zakończone");
			}

			private JFileChooser createFileChooser() {
				JFileChooser fileChooser = new JFileChooser();
				return fileChooser;
			}

		};
		return acL;
	}

	private void writeGraphToFile(Graph g, File result /* String name */) {
		Serializer serializer = new Persister();
		try {
			log.info(result.createNewFile());
		} catch (IOException e) {
			e.printStackTrace(); 
		}

		try {
			serializer.write(g, result);
			System.out.println("zapisane");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void showDialogWithResults(int numberOfTables, long time) {
		JOptionPane.showMessageDialog(parentFrame, "Wyniki\n"
				+ "\nLiczba stołów: " + numberOfTables + "\nCzas obliczeń: "
				+ time + " milisekund");
	}

	protected void showXX() {

	}

	private JMenuItem createMenuItem(ActionListener acL, String name) {
		JMenuItem menuItem = new JMenuItem(name, KeyEvent.VK_T);
		menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1,
				ActionEvent.ALT_MASK));
		menuItem.getAccessibleContext().setAccessibleDescription(
				"This doesn't really do anything");
		menuItem.addActionListener(acL);
		return menuItem;
	}

	public void setParentFrame(JFrame frame) {
		this.parentFrame = frame;
	}
}